package com.simen.hellobytes.socket;

import com.simen.hellobytes.socket.helper.MessageListener;
import com.simen.hellobytes.socket.helper.StatusListener;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * @author Created by Simen.
 * @date 创建日期 2018/5/25 13:43
 * @modify 修改者 Simen
 */
public class UDPServer extends AbstractSocket {

    private int port;

    private DatagramSocket datagramSocket = null;

    private boolean isRunning = false;

    private MessageListener<byte[],DatagramPacket> messageListener = null;

    private StatusListener statusListener;

    public UDPServer(int port) {
        this.port = port;
    }

    public UDPServer(int port, MessageListener<byte[],DatagramPacket> messageListener) {
        this.port = port;
        this.messageListener = messageListener;
    }

    public void listen() {
        isRunning = true;

        try {
            if (statusListener != null) {
                statusListener.onStatus(StatusListener.INIT);
            }

            datagramSocket = new DatagramSocket(port);

            byte[] buf = new byte[bufSize];

            if (statusListener != null) {
                statusListener.onStatus(StatusListener.ALIVE);
            }

            while (isRunning) {

                DatagramPacket request = new DatagramPacket(buf, buf.length);
                datagramSocket.receive(request);

                byte[] data = null;
                int recL = request.getLength();

                if (recL != 0) {
                    data = new byte[recL];

                    System.arraycopy(buf, request.getOffset(), data, 0, recL);
                }

                if (messageListener==null
                        || (messageListener.onMessage(data, recL, request)) == MessageListener.DISCONNECT) {
                    break;
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeImmediately();
        }

        isRunning = false;

        if (statusListener != null) {
            try {
                statusListener.onStatus(StatusListener.DEAD);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void closeImmediately() {
        if (datagramSocket != null) {
            if (datagramSocket.isConnected()) {
                datagramSocket.disconnect();
            }
            datagramSocket.close();
            datagramSocket = null;
        }
    }

    public boolean isRunning() {
        return isRunning;
    }

    public void setRunning(boolean running) {
        isRunning = running;
    }

    public void setMessageListener(MessageListener<byte[],DatagramPacket> messageListener) {
        this.messageListener = messageListener;
    }

    public MessageListener<byte[],DatagramPacket> getMessageListener() {
        return messageListener;
    }

    public StatusListener getStatusListener() {
        return statusListener;
    }

    public void setStatusListener(StatusListener statusListener) {
        this.statusListener = statusListener;
    }
}
